#include "TCP_Client.h"
#include "TCP_Server.h"
#define SQLITE_ENABLE_FTS5 1
#include "Sqlite.h"
#include "STM32.h"

// 客户端处理线程  负责解析客户端指令并执行对应业务（登录、注册、设备控制等）
void *Handle_Client(void *arg)
{

    int client_sock = *(int *)arg; // 客户端套接字（从线程参数获取）
    free(arg);                     // 释放动态分配的参数内存

    sqlite3 *db = Sqlite3_Init_DB(); // 初始化数据库连接（每个客户端单独连接）

    Client client;
    client.sock_fd = client_sock; // 客户端套接字
    client.is_logged_in = 0;      // 未登录状态
    client.username[0] = '\0';    // 用户名初始化为空
    client.family_key[0] = '\0';  // 密钥初始化为空

    // 添加客户端到数组
    pthread_mutex_lock(&client_lock);
    for (int i = 0; i < MAX_CLIENTS; i++) // 遍历客户端数组寻找空位
    {
        if (clients[i].sock_fd == 0)
        {
            clients[i] = client;
            client_count++;
            break;
        }
    }
    pthread_mutex_unlock(&client_lock);

    char buffer[BUFFER_SIZE]; // 接收数据缓冲区
    TCP_Recv_Data(client_sock, buffer);

    memset(buffer, 0, sizeof(buffer));

    while (1)
    {
        // 接收客户端指令
        if (TCP_Recv_Data(client_sock, buffer) == -1)
        {
            break; // 接收失败或客户端断开，退出循环
        }

        // 解析指令（按"|"分割，第一个字段为指令类型）
        char *cmd = strtok(buffer, "|");
        if (cmd == NULL)
            continue; // 空指令忽略

        // 1、登录（LOGIN|用户名|密码|家庭密钥）
        if (strcmp(cmd, "LOGIN") == 0)
        {
            char *username = strtok(NULL, "|");
            char *password = strtok(NULL, "|");
            char *family_key = strtok(NULL, "|");

            // 参数校验
            if (!username || !password || !family_key)
            {
                TCP_Send_Data(client_sock, "\nLOGIN_FAILED|参数不足\n");
                continue;
            }

            // 数据库验证登录
            if (Sqlite3_Login_User(db, username, password, family_key) == 0)
            {
                client.is_logged_in = 1;               // 标记为已登录
                strcpy(client.username, username);     // 记录用户名
                strcpy(client.family_key, family_key); // 保存家庭密钥

                // 更新全局数组中的客户端状态
                pthread_mutex_lock(&client_lock);
                for (int i = 0; i < MAX_CLIENTS; i++)
                {
                    if (clients[i].sock_fd == client_sock)
                    {
                        clients[i] = client; // 将更新后的状态同步到全局数组
                        break;
                    }
                }
                pthread_mutex_unlock(&client_lock);

                // 发送登录成功响应
                char buf[1024] = "";
                TCP_Send_Data(client_sock, "\nLOGIN_SUCCESS|登陆成功\n");
                sprintf(buf, "【家庭群聊系统】：欢迎%s加入群聊\n", username);
                TCP_Send_Data(client_sock, buf);
            }
            else
            {
                TCP_Send_Data(client_sock, "\nLOGIN_FAILED|登录失败\n");
            }
        }
        // 2、注册（REGISTER|用户名|密码|家庭密钥）
        else if (strcmp(cmd, "REGISTER") == 0)
        {
            char *username = strtok(NULL, "|");
            char *password = strtok(NULL, "|");
            char *family_key = strtok(NULL, "|");
            if (!username || !password || !family_key)
            {
                TCP_Send_Data(client_sock, "\nREGISTER_FAILED|参数不足\n");
                continue;
            }
            if (Sqlite3_Register_User(db, username, password, family_key) == 0)
            {
                TCP_Send_Data(client_sock, "\nREGISTER_SUCCESS|注册成功\n");
            }
            else
            {
                TCP_Send_Data(client_sock, "\nREGISTER_FAILED|注册失败\n");
            }
        }
        // 3、设备控制（CONTROL|设备类型|指令）设备类型0-7  指令（0：关闭状态  1：开启状态）
        else if (strcmp(cmd, "CONTROL") == 0)
        {
            if (!client.is_logged_in)
            {
                TCP_Send_Data(client_sock, "\nNOT_LOGGED_IN|未登录\n");
                continue;
            }
            char *dev_str = strtok(NULL, "|"); // 设备类型
            char *cmd_str = strtok(NULL, "|"); // 控制指令
            if (!dev_str || !cmd_str)
            {
                TCP_Send_Data(client_sock, "\nINVALID_CMD|参数不足\n");
                continue;
            }

            // 转换为整数并调用STM32设备控制函数
            DeviceType dev = atoi(dev_str);
            int cmd = atoi(cmd_str);
            STM32_Control_Device(dev, cmd);
            TCP_Send_Data(client_sock, "\nCONTROL_SUCCESS|设备控制成功\n");
        }
        // 4、读取设备状态（READ_STATUS|设备类型）设备类型0-7
        else if (strcmp(cmd, "READ_STATUS") == 0)
        {
            if (!client.is_logged_in)
            {
                TCP_Send_Data(client_sock, "\nNOT_LOGGED_IN|未登录\n");
                continue;
            }
            char *dev_str = strtok(NULL, "|");
            if (!dev_str)
            {
                TCP_Send_Data(client_sock, "\nINVALID_CMD|参数不足\n");
                continue;
            }

            // 读取设备状态并发送给客户端
            DeviceType dev = atoi(dev_str);
            int status = STM32_Read_Device(dev);
            char resp[BUFFER_SIZE];
            sprintf(resp, "\nSTATUS|%d\n", status);
            TCP_Send_Data(client_sock, resp);
        }
        // 5、群聊（CHAT|消息内容）
        else if (strcmp(cmd, "CHAT") == 0)
        {
            if (!client.is_logged_in)
            {
                TCP_Send_Data(client_sock, "\nNOT_LOGGED_IN|未登录\n");
                continue;
            }
            char *msg = strtok(NULL, "|");
            if (!msg)
            {
                TCP_Send_Data(client_sock, "\nINVALID_CMD|参数不足\n");
                continue;
            }

            // 格式化群聊消息（包含用户名）
            char chat_msg[BUFFER_SIZE];
            sprintf(chat_msg, "\nCHAT|%s: %s\n", client.username, msg);

            // 广播消息给所有在线客户端（排除自己）
            pthread_mutex_lock(&client_lock);
            for (int i = 0; i < MAX_CLIENTS; i++)
            {
                if (clients[i].sock_fd != 0 &&                             // 有效连接
                    clients[i].is_logged_in &&                             // 已登录
                    clients[i].sock_fd != client_sock &&                   // 是不是自己
                    strcmp(clients[i].family_key, client.family_key) == 0) // 家庭密钥相同
                {
                    int sent = TCP_Send_Data(clients[i].sock_fd, chat_msg);
                    if (sent < 0)
                    { // 添加错误处理
                        printf("\n向客户端 %d 发送消息失败\n", clients[i].sock_fd);
                    }
                }
            }
            pthread_mutex_unlock(&client_lock);
        }
        // 6、删除用户信息（DELETE|类型(ID/USERNAME)|ID号/用户名|家庭密钥）
        else if (strcmp(cmd, "DELETE") == 0)
        {
            if (!client.is_logged_in)
            {
                TCP_Send_Data(client_sock, "\nNOT_LOGGED_IN\n");
                continue;
            }

            char *type = strtok(NULL, "|");       // 类型(ID/USERNAME)
            char *info = strtok(NULL, "|");       // ID或用户名
            

            if (!type || !info )
            {
                TCP_Send_Data(client_sock, "\nINVALID_CMD|参数不足\n");
                continue;
            }

            // 执行删除操作（按ID或用户名）
            bool is_by_id = (strcmp(type, "ID") == 0); // true 或 false
            int ret = Sqlites3_Delete_User(db, is_by_id, info);

            // 返回删除结果
            if (ret == 1)
            {
                TCP_Send_Data(client_sock, "\nDELETE_SUCCESS|删除成功\n");
            }
            else if (ret == -2)
            {
                TCP_Send_Data(client_sock, "\nDELETE_FAILED|用户不存在\n");
            }
            else
            {
                TCP_Send_Data(client_sock, "\nDELETE_FAILED|删除失败\n");
            }
        } // 7、修改用户信息（UPDATE|旧用户名|旧密码|新用户名|新密码|家庭密钥）
        else if (strcmp(cmd, "UPDATE") == 0)
        {
            if (!client.is_logged_in)
            {
                TCP_Send_Data(client_sock, "\nNOT_LOGGED_IN|未登录\n");
                continue;
            }

            char *old_username = strtok(NULL, "|");
            char *old_password = strtok(NULL, "|");
            char *new_username = strtok(NULL, "|");
            char *new_password = strtok(NULL, "|");
            char *family_key = strtok(NULL, "|");

            if (!old_username || !old_password || !new_username || !new_password || !family_key)
            {
                TCP_Send_Data(client_sock, "\nINVALID_CMD|参数不足\n");
                continue;
            }

            // 权限校验：只能修改当前登录用户
            if (strcmp(client.username, old_username) != 0)
            {
                TCP_Send_Data(client_sock, "\n权限不够,只能修改当前用户信息！！！\n");
                continue;
            }

            // 执行修改操作
            int ret = Sqlites3_Modify_User(db, old_username, old_password, new_username, new_password, family_key);

            // 返回修改结果
            if (ret == 0)
            {
                TCP_Send_Data(client_sock, "\nMODIFY_SUCCESS|修改成功\n");
            }
            else if (ret == -1)
            {
                TCP_Send_Data(client_sock, "\nMODIFY_FAILED|用户不存在\n");
            }
            else if (ret == -2)
            {
                TCP_Send_Data(client_sock, "\nMODIFY_FAILED|新用户名已存在\n");
            }
            else
            {
                TCP_Send_Data(client_sock, "\nMODIFY_FAILED|操作失败\n");
            }
        } // 8、查询用户信息 （QUERY|类型(ID/USERNAME)|ID号/用户名|家庭密钥）
        else if (strcmp(cmd, "QUERY") == 0)
        {
            if (!client.is_logged_in)
            {
                TCP_Send_Data(client_sock, "\nNOT_LOGGED_IN|未登录\n");
                continue;
            }

            char *type = strtok(NULL, "|"); // ID或USERNAME
            char *info = strtok(NULL, "|");

            if (!type || !info)
            {
                TCP_Send_Data(client_sock, "\nINVALID_CMD|参数不足\n");
                continue;
            }

            int ret = -1;
            bool is_by_id = (strcmp(type, "ID") == 0); // true 或 false
            char *result = Sqlites3_Query_User(db, is_by_id, info);

            if (result)
            {
                TCP_Send_Data(client_sock, result);
            }
            else
            {
                TCP_Send_Data(client_sock, "\nQUERY_FAILED|操作失败\n");
            }
        } // 9、帮助
        else if (strcmp(cmd, "HELP") == 0)
        {
            const char *help_msg = "\n1、注册 （REGISTER|用户名|密码|家庭密钥）\n"
                                   "2、登录 （LOGIN|用户名|密码|家庭密钥）\n"
                                   "3、设备控制 （CONTROL|设备类型|指令）设备类型0-7  指令（0：关闭状态  1：开启状态）\n"
                                   "4、读取设备状态 （READ_STATUS|设备类型）设备类型0-7\n"
                                   "5、群聊 （CHAT|消息内容）\n"
                                   "6、删除用户信息 （DELETE|类型(ID/USERNAME)|ID号/用户名）\n"
                                   "7、修改用户信息 （UPDATE|旧用户名|旧密码|新用户名|新密码|家庭密钥）\n"
                                   "8、查询用户信息 （QUERY|类型(ID/USERNAME)|ID号/用户名）\n"
                                   "注意：\t\t\t设备类型\n"
                                   "\t蜂鸣器\t\t0\n"
                                   "\tLED\t\t1\n"
                                   "\t振动马达\t\t2\n"
                                   "\t风扇\t\t3\n"
                                   "\tOLED\t\t4\n"
                                   "\t舵机\t\t5\n"
                                   "\t温湿度传感器\t6\n"
                                   "\t人体红外传感器\t7\n";
            TCP_Send_Data(client_sock, help_msg);
        }
        else
        {
            TCP_Send_Data(client_sock, "\nUNKNOWN_CMD|未知指令\n");
        }
    }

    // 客户端断开连接后的清理工作
    printf("客户端断开连接：%d\n", client_sock);

    // 从客户端数组中移除当前客户端
    pthread_mutex_lock(&client_lock);
    for (int i = 0; i < MAX_CLIENTS; i++)
    {
        if (clients[i].sock_fd == client_sock)
        {
            clients[i].sock_fd = 0; // 标记为无效连接
            client_count--;
            break;
        }
    }
    pthread_mutex_unlock(&client_lock);

    close(client_sock); // 关闭客户端套接字
    sqlite3_close(db);  // 关闭数据库连接
    pthread_exit(NULL); // 退出线程
}